package com.cradom.event.controller;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.cradom.event.model.Account;
import com.cradom.event.model.Children;
import com.cradom.event.model.Event;
import com.cradom.event.model.Personal;
import com.cradom.event.service.ChildrenService;
import com.cradom.event.service.EventService;
import com.cradom.event.service.ImageService;
import com.cradom.event.service.AccountService;
import com.cradom.event.utils.Config;
import com.cradom.event.utils.FilesUpload;
import com.cradom.event.utils.MD5Util;
import com.cradom.event.utils.UUIDUtil;

@Controller
@RequestMapping("/account")
public class AccountController {
    private Producer captchaProducer = null;
    @Resource
    private AccountService accountService;

    @Resource
    private ImageService imageService;

    @Resource
    private EventService eventService;

    @Resource
    private ChildrenService childrenService;

    @Autowired
    public void setCaptchaProducer(Producer captchaProducer) {
        this.captchaProducer = captchaProducer;
    }

    /**
     * 添加账户基本信息
     *
     * @param account
     * @param request
     * @return
     * @throws Exception
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/addAccount")
    public String addAccount(Account account, HttpServletRequest request, String verifyCode, HttpServletResponse response) throws Exception {
        String kaptchaExpected = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY); //验证码
        if (verifyCode != null && verifyCode.toLowerCase().equals(kaptchaExpected.toLowerCase())) {
            String id = UUIDUtil.returnStr(UUID.randomUUID());
            account.setId(id);
            account.setPassword(MD5Util.md5(account.getPassword()));
            account.setRole_id(Config.ROLE_GUARDIAN);
            accountService.addAccount(account);
            request.setAttribute("user_id", id);// 下一页需将将用户编码附给个人信息
            return "forward:/personal.jsp";
        } else {
            request.setAttribute("msg", "验证码错误");
            return "redirect:/account.jsp";
        }
    }

    @RequestMapping("/checkVerifyCode")
    public void checkVerifyCode(String verifyCode, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String kaptchaExpected = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY); //验证码
        request.setCharacterEncoding("utf-8");  //这里不设置编码会有乱码
        response.setContentType("text/html;charset=utf-8");
        response.setHeader("Cache-Control", "no-cache");
        PrintWriter out = response.getWriter();  //输出中文，这一句一定要放到后面，否则中文返回到页面是乱码  
        if (verifyCode.equals(kaptchaExpected)) {
            out.print("true");
        } else {
            out.print("false");
        }
    }

    /**
     * 添加个人信息，非帐号
     *
     * @param personal
     * @param request
     * @return
     */
    @RequestMapping("/addPersonal")
    public String addPersonnal(Personal personal, HttpServletRequest request) {
        String id = UUIDUtil.returnStr(UUID.randomUUID());
        personal.setId(id);
        accountService.addPersonnal(personal);
        request.setAttribute("user_id", personal.getUser_id());
        return "forward:/children.jsp";
    }

    /**
     * 添加宠物信息
     *
     * @param children
     * @param request
     * @return
     * @throws Exception
     * @throws IllegalStateException
     */
    @RequestMapping("/addChildren")
    public String addChildren(Children children,
                              @RequestParam("files") MultipartFile[] files,
                              HttpServletRequest request,
                              @RequestParam("current_id") String current_id,
                              @RequestParam("children_id") String children_id
    ) throws IllegalStateException, Exception {
        String root = request.getServletContext().getRealPath("/upload");
        int i = 1;
        if (current_id == null || current_id.equals("") && children_id == null || children_id.equals("")) {
            String id = UUIDUtil.returnStr(UUID.randomUUID());
            children.setId(id);
            accountService.addChildren(children);
            for (MultipartFile file : files) {
                imageService.addImage(FilesUpload.filesUpload(file, root, children.getId(), i));
                i++;
            }
            request.setAttribute("children_id", children.getId());
        } else {
            children.setId(children_id);
            children.setGuardian_id(current_id);
            childrenService.updateChildren(children);
            for (MultipartFile file : files) {
                imageService.addImage(FilesUpload.filesUpload(file, root, children_id, i));
                i++;
            }
            request.setAttribute("children_id", children.getId());
        }
        return "forward:/event.jsp";
    }

    /**
     * springMVC时间，可以改成拦截器
     *
     * @param strTime
     * @param event_point
     * @param content
     * @param children_id
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("/addEvent")
    public String addEvent(@RequestParam("event_time") String strTime, @RequestParam("event_point") String event_point,
                           @RequestParam("content") String content, @RequestParam("children_id") String children_id,
                           HttpServletRequest request) throws Exception {
        String id = UUIDUtil.returnStr(UUID.randomUUID());
        Event event = new Event();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date event_time = sdf.parse(strTime);
        Date submit_time = new Timestamp(System.currentTimeMillis());
        event.setEvent_time(event_time);
        event.setChildren_id(children_id);
        event.setContent(content);
        event.setEvent_point(event_point);
        event.setSubmit_time(submit_time);
        event.setId(id);
        accountService.addEvent(event);
        return "redirect:/index.do";
    }

    /**
     * 登录
     *
     * @param account
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("/login")
    public String login(Account account, HttpServletRequest request) throws UnsupportedEncodingException, Exception {
        Subject subject = SecurityUtils.getSubject();
        System.out.println(MD5Util.md5(account.getPassword()));
        UsernamePasswordToken token = new UsernamePasswordToken(account.getPhone(), MD5Util.md5(account.getPassword()));
        try {
            subject.login(token);
            Session session = subject.getSession();
            String id = accountService.getIdByPhone(account.getPhone());
            account.setId(id);
            session.setAttribute("user", account);
            return "redirect:/index.do";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/error.jsp";
        }
    }


    @RequestMapping("/logout")
    public String logout(HttpSession httpSession) throws Exception {
        try {
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
            //httpSession.invalidate();
            return "redirect:/index.do";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/error.jsp";
        }
    }

    /**
     * 后台登录
     *
     * @param account
     * @param request
     * @return
     * @throws Exception
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/adminLogin")
    public String adminLogin(Account account, HttpServletRequest request) throws UnsupportedEncodingException, Exception {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token
                = new UsernamePasswordToken(account.getPhone(), MD5Util.md5(account.getPassword()));
        try {
            subject.login(token);
            Session session = subject.getSession();
            session.setAttribute("admin", account);
            return "redirect:/admin/index.jsp";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/admin/error.jsp";
        }
    }

    @RequestMapping("/captcha-image")
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.  
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).  
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.  
        response.setHeader("Pragma", "no-cache");
        // return a jpeg  
        response.setContentType("image/jpeg");
        // create the text for the image  
        String capText = captchaProducer.createText();
        System.out.println(capText);
        // store the text in the session  
        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
        // create the image with the text  
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        // write the data out  
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
        return null;
    }

}